package com.mycompany.project.client;




import java.util.LinkedList;

import com.google.gwt.user.client.Random;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;


public class CloudTagLinks extends Canvas {
	
	private LinkedList<CloudTagElement> keywordsList;
	private int minFrequence;
	private int maxfrequence;
	public static final int TAG_CLOUD_FONTS_NUMBER=10;
	private LinkedList<TagCloudFontElement> cloudElementFontsList;
	private LinkedList<Label> cloudElementsWordlist;
	
	
	public CloudTagLinks(int xPos,int yPos, int width, int height){
		keywordsList=new LinkedList<CloudTagElement>();
		setStyleName("CloudTagPanel");
		setSize(width + "px", height + "px");
		setPageLeft(xPos);					
		setPageTop(yPos);	
		minFrequence=0;
		maxfrequence=0;
		cloudElementFontsList=new LinkedList<TagCloudFontElement>();
		cloudElementsWordlist=new LinkedList<Label>();
		
		
		cloudElementFontsList.add(new TagCloudFontElement("smallestCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("smallestsmallCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("smallCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("smallMediumCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("mediumCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("mediumLargeCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("largeCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("largeLargestCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("largestCloudTag"));
		cloudElementFontsList.add(new TagCloudFontElement("PluslargestCloudTag"));
		
	}

	private boolean updateKeyWordIfPresent(String keyWord){
		boolean returnValue=false;
		int counter=0;
		
		while(counter<keywordsList.size()){
			if(keywordsList.get(counter).getkeyWordValue().compareToIgnoreCase(keyWord)==0){				
				keywordsList.get(counter).incrementKeyWordCounter();				
				counter=keywordsList.size()+1;
				returnValue=true;
				refreshTag();
			}
			counter++;
		}
		return(returnValue);
	}
	
	
	public void addKeyWord(String keyWord){
		if(!updateKeyWordIfPresent(keyWord)){
			keywordsList.add(new CloudTagElement(keyWord));			
			refreshTag();
		}
		
	}
	
	
	public void changeKeyWord(String oldKeyWord, String newKeyWord){
		int counter=0;
		
		while(counter<keywordsList.size()){
			if(keywordsList.get(counter).getkeyWordValue().compareToIgnoreCase(oldKeyWord)==0){
				if(keywordsList.get(counter).getKeyWordCounter()>1){ // if exists more than one keyword with this value
					keywordsList.get(counter).decreaseKeyWordCounter();
					addKeyWord(newKeyWord);
				} else {
					keywordsList.get(counter).setkeyWordValue(newKeyWord); //update new keyword value
					refreshTag();
				}
				counter=keywordsList.size()+1; // to exit while cycle
			}
			counter++;
		}
	}
	

	
	private void calculateMinMaxFrequency(){
		int counter=0;
		maxfrequence=1;
		minFrequence=1;
		
		// create a ordered keyword list
		while(counter<keywordsList.size()){			
		    if(keywordsList.get(counter).getKeyWordCounter()>maxfrequence)
		    	maxfrequence=keywordsList.get(counter).getKeyWordCounter();
		    else if(keywordsList.get(counter).getKeyWordCounter()<minFrequence)
		    	minFrequence=keywordsList.get(counter).getKeyWordCounter();	
		    counter++;
		}
	}
	
	
	private void setFontStyleName(Label keyWord,int frequecy){
		int counter=cloudElementFontsList.size()-1;
		
		while(counter>=0){
			//Window.alert(cloudElementFontsList.get(counter).getStyleNameFont());
			if((frequecy<=cloudElementFontsList.get(counter).getEndRange()) && (frequecy>=cloudElementFontsList.get(counter).getStartRange())){				
				keyWord.setStyleName(cloudElementFontsList.get(counter).getStyleNameFont());
				//DOM.setStyleAttribute(keyWord.getElement(), "background-color", "blue"); //set label color black
				//Window.alert(keyWord.getContents() + ": " + cloudElementFontsList.get(counter).getStyleNameFont()+  " assigned");
				counter=-1;
			}
			counter--;
		}
		
	}
	
	private void clearWordList(){
		while(cloudElementsWordlist.size()>0){  // create fonts range list			
			this.removeChild(cloudElementsWordlist.get(0));
			cloudElementsWordlist.get(0).clear();
			cloudElementsWordlist.remove(0);
		}
		
		cloudElementsWordlist.clear();
	}
	
	
	private void createFontListRange(int maxfrequenceValue, int minFrequenceValue ){
		double rangeValues;
		double createRanges;
		int counter=0;		
		
		if(cloudElementsWordlist.size()<cloudElementFontsList.size()){
			counter=cloudElementFontsList.size()-1;
			while(maxfrequenceValue>= minFrequenceValue){
				cloudElementFontsList.get(counter).setEndRange(maxfrequenceValue);
				maxfrequenceValue-=1;
				cloudElementFontsList.get(counter).setStartRange(maxfrequenceValue+0.1);
				counter-=1;
			}
			while(counter>=0){
				cloudElementFontsList.get(counter).setStartRange(0);				
				cloudElementFontsList.get(counter).setEndRange(0);
				counter--;
			}
			/*
			//debug
			counter=cloudElementFontsList.size()-1;
			while(counter>0){
				Window.alert("cloud font range values: " + cloudElementFontsList.get(counter).getStartRange() + " " + cloudElementFontsList.get(counter).getEndRange());
				counter--;
			}
			 */			
		}			
		else{
			rangeValues=(((double)(maxfrequenceValue-minFrequenceValue))/TAG_CLOUD_FONTS_NUMBER);
			//Window.alert(rangeValues +" ");
			createRanges=minFrequenceValue;
			counter=0;
			while(counter< cloudElementFontsList.size()){  // create fonts range list
				cloudElementFontsList.get(counter).setStartRange(createRanges);
				createRanges+=rangeValues;
				cloudElementFontsList.get(counter).setEndRange(createRanges);
				//TagCloudFontElement tmpvalue=cloudElementFontsList.get(counter);
				//Window.alert(tmpvalue.getStyleNameFont()+": " + tmpvalue.getStartRange() + "/" + tmpvalue.getEndRange());
				counter++;
			}
		}						
	}
	
	
	private void refreshTag(){
		int counter=0;			
		
		Label tmpLabelWordTag;
		CloudTagLinksAdministrator tagLinksPositionAdministrator;		
		//this.clear();		
		clearWordList(); // clear Word List		
		calculateMinMaxFrequency(); // calculate max and min frequency word				
		createFontListRange(maxfrequence,minFrequence);		
		//tagCloudElementsPosition=new TagCloudListPositionElement();
		tagLinksPositionAdministrator=null;
		tagLinksPositionAdministrator=new CloudTagLinksAdministrator(this);
		counter=0;
		while(counter<keywordsList.size()){	
			tmpLabelWordTag=setGetLabelWordTagProperty(keywordsList.get(counter).getkeyWordValue());
			setFontStyleName(tmpLabelWordTag,keywordsList.get(counter).getKeyWordCounter());
			cloudElementsWordlist.add(tmpLabelWordTag);			
			tagLinksPositionAdministrator.addLabelTag(tmpLabelWordTag);	
			counter++;
		}
		setWordTagCentral(tagLinksPositionAdministrator.getTopYPosition(), tagLinksPositionAdministrator.getBottomYPosition(),tagLinksPositionAdministrator.getLeftXPosition(),tagLinksPositionAdministrator.getRigthXPosition());
		
	}	
	
	
	private void setWordTagCentral(int topY,int bottomY,int leftX, int rightX){
		int heightWordTag=bottomY-topY;
		int widthWordTag=rightX-leftX;
		int incrementsY= (getOffsetHeight()-heightWordTag)/2;
		int incrementsX= (getOffsetWidth()-widthWordTag)/2;
		int counter=0;
		Label tmpLabelToMove;
		
		//if(incrementsX<=0)
			//Window.alert("Incremento= " + incrementsX );
		//Window.alert("Begin Movements -- heigth pnel=" + getOffsetHeight() + " Word tags height=" + heightWordTag + " increments=" + incrementsY);
		//Window.alert("Begin Movements -- width pnel=" + getOffsetWidth() + " Word tags width=" + widthWordTag + " increments=" + incrementsX);
		while(counter< cloudElementsWordlist.size()){  // create fonts range list
			tmpLabelToMove=cloudElementsWordlist.get(counter);
		//	Window.alert("Posizione Prima del movimento:" +  tmpLabelToMove.getAbsoluteLeft() + "/" + tmpLabelToMove.getAbsoluteTop());
			tmpLabelToMove.moveBy(incrementsX, incrementsY);
			//tmpLabelToMove.moveTo(tmpLabelToMove.getAbsoluteLeft(),tmpLabelToMove.getAbsoluteTop()+increments);
		//	Window.alert("Posizione dopo del movimento:" +  tmpLabelToMove.getAbsoluteLeft() + "/" + tmpLabelToMove.getAbsoluteTop());			
			++counter;
		}
		
	}
	
	
	private Label setGetLabelWordTagProperty(String worLabel){
		Label tmpLabelWT;		
		tmpLabelWT=new Label(worLabel);
		tmpLabelWT.setCanDragReposition(true);
		tmpLabelWT.setAutoWidth();
		tmpLabelWT.setAutoHeight();	
		tmpLabelWT.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				// TODO Auto-generated method stub
				
			}
		});
		return(tmpLabelWT);		
	}
	


	/**
	 * This method return a random color value choosing it between 22 different color.
	 * @return return a string with the name random color.
	 */
	public static final String getRandomColor(){
		String color;
		
		int valueRandom= Random.nextInt(20);
		
		switch (valueRandom) {
		case 0: color="Crimson";			
				break;
		case 1: color="BlueViolet";			
				break;
		case 2: color="Chartreuse";			
				break;
		case 3: color="Crimson";			
				break;
		case 4: color="DarkViolet";			
				break;
		case 5: color="DeepPink";			
				break;
		case 6: color="DeepSkyBlue";			
				break;
		case 7: color="GreenYellow";			
				break;
		case 8: color="HotPink";			
				break;
		case 9: color="Indigo";			
				break;
		case 10: color="Lavender";			
				break;
		case 11: color="LightSeaGreen";			
				break;
		case 12: color="LimeGreen";			
				break;
		case 13: color="MediumVioletRed";			
				break;
		case 14: color="OrangeRed";			
				break;
		case 15: color="RoyalBlue";			
				break;
		case 16: color="Yellow";			
				break;
		case 17: color="Beige";			
				break;
		case 18: color="Gold";			
				break;
		case 19: color="Linen";			
				break;
		case 20: color="Blue";			
				break;				
		default: color="Green";
				break;
		}
		return(color);
	}
	
	
	
	
	/**
	 * Debug
	 */
	public String getCloudValue(){
		int counter=0;
		String returnValue="";
		while(counter<keywordsList.size()){
			returnValue=returnValue+ keywordsList.get(counter).getkeyWordValue() + " : " + keywordsList.get(counter).getKeyWordCounter() + "\n\r";
			counter++;
		}
		
		return returnValue;
	}
}

